package com.syyo.generator.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.syyo.common.constant.SettingsConstant;
import com.syyo.common.enums.ResultEnum;
import com.syyo.common.exception.SysException;
import com.syyo.common.utils.CheckParamUtils;
import com.syyo.common.utils.MyDateUtils;
import com.syyo.common.utils.MyFileUtil;
import com.syyo.common.utils.MyStringUtils;
import com.syyo.generator.domain.Column;
import com.syyo.generator.domain.JavaProperties;
import com.syyo.generator.domain.entity.GeneratorEntity;
import com.syyo.generator.domain.req.GeneratorReq;
import com.syyo.generator.mapper.DatasourcesMapper;
import com.syyo.generator.mapper.GeneratorMapper;
import com.syyo.generator.service.GeneratorService;
import com.syyo.generator.utils.GeneratorUtils;
import com.syyo.generator.utils.MyZipUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.List;
import java.util.Map;

/**
* @author wang
* @date 2020-08-20
*/
@Service
public class GeneratorServiceImpl extends ServiceImpl<GeneratorMapper, GeneratorEntity> implements GeneratorService {

    @Autowired
    private GeneratorMapper generatorMapper;

    @Autowired
    private DatasourcesMapper datasourcesMapper;

    @Autowired
    private SettingsConstant settingsConstant;

    /**
    * 新增
    * @return ResultVo
    */
    @Override
    public int generator(String tableName){

        if (!settingsConstant.getGeneratorSwitch()){
            // 生产环境不开启代码生成器
            throw new SysException(ResultEnum.E_80046.getCode(),ResultEnum.E_80046.getMessage());
        }

        // 根据表名查询该表的生成器配置
        QueryWrapper<GeneratorEntity> wrapper = new QueryWrapper<>();
        wrapper.like("table_name",tableName);
        GeneratorEntity generator = generatorMapper.selectOne(wrapper);
        if (generator == null){
            throw new SysException(ResultEnum.E_80044.getCode(),ResultEnum.E_80044.getMessage());
        }
        String modelNameFull = generator.getModuleName();// "syyo-generator";模块名
        // syyo-generator  去掉-的前缀 ，generator
        String[] split = modelNameFull.split("-");
        if (split.length<2){
            throw new SysException(ResultEnum.E_80045.getCode(),ResultEnum.E_80045.getMessage());
        }
        String modelName = split[1];
        String packageName = generator.getPack();
        String author = generator.getAuthor();
        Boolean cover = generator.getCover();
        String apiPath = generator.getApiPath();
        String apiName = generator.getApiName();
        List<Column> columns = datasourcesMapper.findColumn(tableName);
        String lowerClassName = MyStringUtils.toSmallHumpStr(tableName);
        String BigHumpStr = MyStringUtils.toBigHumpStr(tableName);
        String dateStr2 = MyDateUtils.getDateStr2();
        JavaProperties userEntity = new JavaProperties(tableName,packageName,modelNameFull,modelName, BigHumpStr,lowerClassName,author,dateStr2,apiName);

        for (int i = 0; i < columns.size(); i++) {
            Column column = columns.get(i);
            String smallHumpStr = MyStringUtils.toSmallHumpStr(column.getColumnName());
            String columnType = typeCast(column.getColumnType());
            // 默认数据库第一个字段是主键
            if (i ==0){
                userEntity.addField(columnType, smallHumpStr,column.getColumnName(),column.getColumnComment(),true);
            }else {
                userEntity.addField(columnType, smallHumpStr,column.getColumnName(),column.getColumnComment(),false);
            }
        }
        GeneratorUtils.createTemplates(userEntity,"",cover,apiPath);
        return 1;
    }

    /**
     * 数据库和java类型转换
     * @param columnType
     * @return
     */
    private String typeCast(String columnType) {
        switch(columnType){
            case "tinyint": return "Integer";
            case "int": return "Integer";
            case "bigint": return "Long";
            case "float": return "Float";
            case "double": return "Double";
            case "decimal": return "BigDecimal";
            case "varchar": return "String";
            case "date": return "LocalDate";
            case "datetime": return "LocalDateTime";
            default: return "String";
        }
    }

    /**
    * 预览
    * @return ResultVo
    */
    @Override
    public List<Map<String, String>> preview(String tableName) {
        QueryWrapper<GeneratorEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("table_name",tableName);
        GeneratorEntity generator = generatorMapper.selectOne(wrapper);
        if (generator == null){
            throw new SysException(ResultEnum.E_80044.getCode(),ResultEnum.E_80044.getMessage());
        }
        String modelNameFull = generator.getModuleName();// "syyo-generator";模块名
        // syyo-generator  去掉-的前缀 ，generator
        String[] split = modelNameFull.split("-");
        if (split.length<2){
            throw new SysException(ResultEnum.E_80045.getCode(),ResultEnum.E_80045.getMessage());
        }
        String modelName = split[1];
        String packageName = generator.getPack();
        String author = generator.getAuthor();
        String apiName = generator.getApiName();
        List<Column> columns = datasourcesMapper.findColumn(tableName);
        String lowerClassName = MyStringUtils.toSmallHumpStr(tableName);// 表名小驼峰
        String BigHumpStr = MyStringUtils.toBigHumpStr(tableName); // 表名大驼峰
        String dateStr2 = MyDateUtils.getDateStr2();
        JavaProperties userEntity = new JavaProperties(tableName,packageName,modelNameFull,modelName, BigHumpStr,lowerClassName,author,dateStr2,apiName);
        for (int i = 0; i < columns.size(); i++) {
            Column column = columns.get(i);
            String smallHumpStr = MyStringUtils.toSmallHumpStr(column.getColumnName());
            String columnType = typeCast(column.getColumnType());
            if (i ==0){
                userEntity.addField(columnType, smallHumpStr,column.getColumnName(),column.getColumnComment(),true);
            }else {
                userEntity.addField(columnType, smallHumpStr,column.getColumnName(),column.getColumnComment(),false);
            }
        }
        return GeneratorUtils.previewTemplates(userEntity);
    }

    /**
    * 下载
    * @return ResultVo
    */
    @Override
    public Object download(String tableName, HttpServletRequest request, HttpServletResponse response){
        QueryWrapper<GeneratorEntity> wrapper = new QueryWrapper<>();
        wrapper.like("table_name",tableName);
        GeneratorEntity generator = generatorMapper.selectOne(wrapper);
        if (generator == null){
            throw new SysException(ResultEnum.E_80044.getCode(),ResultEnum.E_80044.getMessage());
        }
        String modelNameFull = generator.getModuleName();// "syyo-generator";模块名
        // syyo-generator  去掉-的前缀 ，generator
        String[] split = modelNameFull.split("-");
        if (split.length<2){
            throw new SysException(ResultEnum.E_80045.getCode(),ResultEnum.E_80045.getMessage());
        }
        String modelName = split[1];
        String packageName = generator.getPack();
        String author = generator.getAuthor();
        Boolean cover = generator.getCover();
        String apiName = generator.getApiName();
        List<Column> columns = datasourcesMapper.findColumn(tableName);
        String lowerClassName = MyStringUtils.toSmallHumpStr(tableName);// 表名小驼峰
        String BigHumpStr = MyStringUtils.toBigHumpStr(tableName); // 表名大驼峰
        String dateStr2 = MyDateUtils.getDateStr2();
        JavaProperties userEntity = new JavaProperties(tableName,packageName,modelNameFull,modelName, BigHumpStr,lowerClassName,author,dateStr2,apiName);
        for (int i = 0; i < columns.size(); i++) {
            Column column = columns.get(i);
            String smallHumpStr = MyStringUtils.toSmallHumpStr(column.getColumnName());
            String columnType = typeCast(column.getColumnType());
            if (i ==0){
                userEntity.addField(columnType, smallHumpStr,column.getColumnName(),column.getColumnComment(),true);
            }else {
                userEntity.addField(columnType, smallHumpStr,column.getColumnName(),column.getColumnComment(),false);
            }
        }
        // 获取临时文件路劲
        String temporaryPath = createTemporaryPath();
        // 创建代码文件
        GeneratorUtils.createTemplates(userEntity,temporaryPath,cover,"");

        File directory = new File(temporaryPath);

        File[] array = directory.listFiles();
        // 压缩后的文件全名
        String zipFilePath = temporaryPath + System.currentTimeMillis() + ".zip";
        File file = new File(zipFilePath);
        FileOutputStream fos2 = null;
        try {
            fos2 = new FileOutputStream(file);
            // 压缩文件
            MyZipUtils.toZip(array, fos2);
            MyFileUtil.downloadFile(request,response,file,true);
            MyFileUtil.del(zipFilePath);
            // 删除临时文件
            for (File file1 : array) {
                MyFileUtil.del(file1);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取当前generator模块的临时路劲
     * @return
     */
    private String createTemporaryPath() {
        String rootPath = System.getProperty("user.dir");
        String sprit = File.separator;//获取系统的斜杠
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append(rootPath);
        stringBuffer.append(sprit);
        stringBuffer.append("syyo-generator");
        stringBuffer.append(sprit);
        stringBuffer.append("src");
        stringBuffer.append(sprit);
        stringBuffer.append("main");
        stringBuffer.append(sprit);
        stringBuffer.append("resources");
        stringBuffer.append(sprit);
        stringBuffer.append("temporary");
        stringBuffer.append(sprit);
        return stringBuffer.toString(); // 临时文件目录

    }


    /**
    * 添加或修改代码生成器表配置
    */
    @Override
    @Transactional
    public int addConfig(GeneratorReq req){
        //  参数校验
        CheckParamUtils.validate(req);
        QueryWrapper<GeneratorEntity> wrapper = new QueryWrapper<>();
        wrapper.like("table_name",req.getTableName());
        GeneratorEntity generator = generatorMapper.selectOne(wrapper);
        GeneratorEntity generatorEntity = new GeneratorEntity();
        generatorEntity.setTableName(req.getTableName());
        generatorEntity.setAuthor(req.getAuthor());
        generatorEntity.setModuleName(req.getModuleName());
        generatorEntity.setPack(req.getPack());
        generatorEntity.setCover(req.getCover());
        generatorEntity.setApiName(req.getApiName());
        generatorEntity.setApiPath(req.getApiPath());
        if (generator == null){
            // 添加
            int insert = generatorMapper.insert(generatorEntity);
            if (insert != 1){
                throw new SysException(ResultEnum.E_80041.getCode(),ResultEnum.E_80041.getMessage());
            }
        }else {
            // 修改
            generatorEntity.setId(generator.getId());
            int update = generatorMapper.updateById(generatorEntity);
            if (update != 1){
                throw new SysException(ResultEnum.E_80043.getCode(),ResultEnum.E_80043.getMessage());
            }
        }
        return 1;
    }

    /**
    * 列表
    */
    @Override
    public IPage<GeneratorEntity> findAll(Integer pageNum, Integer pageSize, GeneratorReq req){
        Page<GeneratorEntity> teacherPage = new Page<GeneratorEntity>(pageNum,pageSize);
        QueryWrapper<GeneratorEntity> wrapper = new QueryWrapper<>();
        return generatorMapper.selectPage(teacherPage, wrapper);
    }

    /**
     * 查询代码生成器表配置
     */
    @Override
    public GeneratorEntity getConfig(String tableName) {
        QueryWrapper<GeneratorEntity> wrapper = new QueryWrapper<>();
        wrapper.like("table_name",tableName);
        return generatorMapper.selectOne(wrapper);
    }

}